﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CollegeShop.Infrastructure.Entities.Entity;
using CollegeShop.Infrastructure.Entities;
using CollegeShop.Infrastructure.Component.Cache;
using CollegeShop.Infrastructure.Entities.Enum;
using CollegeShop.Tool.Framework;
using System.Data;
using CollegeShop.Infrastructure.Component.Support;

namespace CollegeShop.Biz
{
    public class CommodityBiz
    {
        public static List<Goods> LoadPopular(int pageSize)
        {
            return iCache.Get("CommodityBiz.LoadPopular_{" + pageSize.ToString() + "}",
                () =>
                {
                    using (Context ctx = new Context())
                    {
                        DataTable dt = ctx.ExcuteSQL("select g.*,r.Path from t_goods g join t_resource r on g.resourceid = r.id where g.id in (select goodsid from t_orderdetail where goodsid > 0 group by goodsid order by count(goodsid) desc) limit " + pageSize);
                        if (dt != null && dt.Rows.Count > 0)
                        {
                            List<Goods> popular = new List<Goods>();
                            foreach (DataRow row in dt.Rows)
                            {
                                popular.Add(new Goods()
                                {
                                    ID = row["ID"].ToInt32(),
                                    GoodsCode = row["GoodsCode"].ToString(),
                                    GoodsName = row["GoodsName"].ToString(),
                                    GoodsNamePY = row["GoodsNamePY"].ToString(),
                                    GoodsTitel = row["GoodsTitel"].ToString(),
                                    GoodsCategoryID = row["GoodsCategoryID"].ToInt32(),
                                    Standard = row["Standard"].ToString(),
                                    Unit = row["Unit"].ToString(),
                                    PackStandard = row["PackStandard"].ToInt32(),
                                    GoodsDescription = row["GoodsDescription"].ToString(),
                                    Style = row["Style"].ToString(),
                                    DefaultSalePrice = row["DefaultSalePrice"].ToDecimal(0),
                                    State = row["State"].ToInt32(),
                                    ResourceId = row["ResourceId"].ToInt32(),
                                    SaleListId = row["SaleListId"].ToInt32(),
                                    Resource = new Infrastructure.Entities.Repository.Resource()
                                    {
                                        Path = row["Path"].ToString()
                                    }
                                });
                            }
                            return popular;
                        }
                    }
                    return null;
                }, 6000);
        }
        public static Dictionary<int, List<SaleList>> LoadSaleList()
        {
            var host = System.Web.HttpContext.Current.Request.Url.Host;
            if (host.StartsWith("www."))
            {
                host = host.Substring(4);
            }
            return iCache.Get("LoadSaleList_" + host, () => {
                using (Context ctx = new Context())
                {
                    var data = (from c in ctx.SaleList
                               join r in ctx.Resource
                                on c.ResourceId equals r.ID
                               group new {c,r} by c.GoodsCategoryID into g
                               select g)
                               .ToDictionary(
                                k => k.Key,
                                v => v.Select(c=>new SaleList().Set(c.c)
                                    .LoadResource(c.r)).ToList()
                               );
                    return data;
                }
            }, 0);
        }

        public static List<Goods> LoadAllCommodities(int salelistId)
        {
            var host = System.Web.HttpContext.Current.Request.Url.Host;
            if(host.StartsWith("www."))
            {
                host = host.Substring(4);
            }
            return iCache.Get(String.Format("LoadAllCommodities_{0}_{1}", host, salelistId.ToString()), () =>
            {
                using (Context ctx = new Context())
                {
                    var data = (from c in ctx.Goods
                                join r in ctx.Resource
                                 on c.ResourceId equals r.ID
                                where c.SaleListId == salelistId
                                select new { c, r})
                                .ToList()
                                .Select(c=>new Goods().Set(c.c).LoadResource(c.r))
                                .ToList();
                    return data;
                }
            },0);
            
        }

        public static Goods LoadCommodity(int id)
        {
            var host = System.Web.HttpContext.Current.Request.Url.Host;
            if (host.StartsWith("www."))
            {
                host = host.Substring(4);
            }
            return iCache.Get<Goods>(String.Format("LoadCommodity_{0}_{1}", host, id),
                () => {
                    using (Context ctx = new Context())
                    {
                        var data = (from c in ctx.Goods
                                    join r in ctx.Resource
                                     on c.ResourceId equals r.ID
                                    where c.ID == id
                                    select new { c, r })
                                   .FirstOrDefault();
                        if (data != null)
                        {
                            var goods = new Goods().Set(data.c).LoadResource(data.r);
                            return goods;
                        }
                        return null;
                    }
                },0);
        }

        public static Order SubmitOrder(List<OrderModel> model,Deliveryaddress address, bool isLogin = true)
        {
            if (model != null && model.Any() && address != null)
            {
                Salesunit salesunit = new Salesunit().Find(address.SalesUnitID.ToString());
                if (salesunit == null)
                {
                    if (isLogin)
                    {
                        address.PostDelete();
                    }
                    return null;
                }
                Order order = new Order()
                {
                    OrderNumber = GetOrderNumber(model.First().goods.GoodsCode),
                    BuyClient = 1,
                    BuyUser = System.Web.HttpContext.Current.User.Identity.IsAuthenticated ?
                        System.Web.HttpContext.Current.User.Identity.Name : "Ghost",
                    BuyWay = 1,
                    DeliveryAddress = String.Format("{0} {1} {2}", CollegeManager.getCollegeName(),
                        salesunit.SalesUnitName, address.Address),
                    LinkMan = address.LinkMan,
                    LinkPhone = address.LinkPhone,
                    OrderClient = ClientType.Browser,
                    OrderTime = DateTime.Now,
                    Payway = PayWay.Offline,
                    SalesUnitID = salesunit.ID,
                    State = OrderState.Payed
                };
                if (order.PostAdd() == null)
                {
                    LogHelper.Write(CommonLogger.Order, LogLevel.Error, "创建订单失败" + Environment.NewLine + order.ToJson());
                    return null;
                }
                List<Orderdetail> details = new List<Orderdetail>();
                foreach (var item in model)
                {
                    Orderdetail detail = new Orderdetail()
                    {
                        GoodsAmount = item.Amount,
                        GoodsID = item.goods.ID,
                        GoodsName = item.goods.GoodsName,
                        GoodsPrice = item.goods.DefaultSalePrice * item.Amount,
                        OrderID = order.ID
                    };
                    if (detail.PostAdd() == null) {
                        LogHelper.Write(CommonLogger.Order, LogLevel.Error, "创建订单详情失败" + Environment.NewLine + order.ToJson());
                        continue;
                    }
                    order.GoodsDescript += String.Format("<p>{0} {1},{2} (*{3})</p>", item.goods.GoodsTitel, item.goods.Standard,
                        item.goods.Style, item.Amount);
                    order.TotalAmount += item.Amount;
                    order.TotalMoney += detail.GoodsPrice;
                }
                var isMember = false;
                if (isLogin)
                {
                    if (new User().Find(order.BuyUser) != null)
                    {
                        isMember = true;
                    }
                }
                if (isMember)
                {
                    //会员5元以下加收0.5元配送费用
                    if (order.TotalMoney < 5)
                    {
                        order.TotalMoney += new decimal(0.5);
                        order.GoodsDescript += String.Format("<p>{0} {1},{2} (*{3})</p>", "会员购物未满5元加收0.5元配送费", "送货上门",
                            "配送费", 1);

                        new Orderdetail()
                        {
                            GoodsAmount = 1,
                            GoodsID = 0,
                            GoodsName = "会员购物未满5元加收0.5元配送费",
                            GoodsPrice = new decimal(0.5),
                            OrderID = order.ID
                        }.PostAdd();
                    }
                }
                else
                {
                    //游客7元以下加收0.5元配送费用
                    if (order.TotalMoney < 7)
                    {
                        order.TotalMoney += new decimal(0.5);
                        order.GoodsDescript += String.Format("<p>{0} {1},{2} (*{3})</p>", "游客购物未满7元加收0.5元配送费", "送货上门",
                            "配送费", 1);

                        new Orderdetail()
                        {
                            GoodsAmount = 1,
                            GoodsID = 0,
                            GoodsName = "游客购物未满7元加收0.5元配送费",
                            GoodsPrice = new decimal(0.5),
                            OrderID = order.ID
                        }.PostAdd();
                    }
                }

                if (order.PostModify() == null) 
                {
                    LogHelper.Write(CommonLogger.Order, LogLevel.Error, "更新订单所含商品信息失败" + Environment.NewLine + order.ToJson());
                }
                return order;
            }
            return null;
        }

        private static string GetOrderNumber(string goodsCode)
        {
            return CollegeManager.GetCollegeCode() + DateTime.Now.ToString("yyMMddHHmmss") + goodsCode.PadLeft(6, '0') + new Random().Next(1, 100).ToString().PadLeft(3, '0');
        }

        #region Staff
        public static List<Order> GetPendingOrders(string userName)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                var user = new User().Find(userName);
                if (user != null && user.SalesUnitID > 0)
                {
                    var saleUnit = new Salesunit().Find(user.SalesUnitID.ToString());
                    if (saleUnit != null)
                    {
                        var data = new Order().FindAll(c => c.SalesUnitID == saleUnit.ID && c.State == (int)OrderState.Payed,
                            c => c.OrderTime, false, 0, 5);
                        return data;
                    }
                }
            }
            return null;
        }
        public static ItemListBox<Order> GetOrders(string userName,int page=0)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                var user = new User().Find(userName);
                if (user != null && user.SalesUnitID > 0)
                {
                    var saleUnit = new Salesunit().Find(user.SalesUnitID.ToString());
                    if (saleUnit != null)
                    {
                        var data = new Order().FindAll(c => c.SalesUnitID == saleUnit.ID,
                            c => c.OrderTime,true , page, 15);
                        return new ItemListBox<Order>(data).BuildPage(
                            new Order().Count(c => c.SalesUnitID == saleUnit.ID),
                            page, 15, new PageParameter() { Style = "home" });
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="month">如果只需要当月：true 否则false</param>
        /// <returns></returns>
        public static decimal GetSalesAmount(string userName, bool month = true)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                var user = new User().Find(userName);
                if (user != null && user.SalesUnitID > 0)
                {
                    var saleUnit = new Salesunit().Find(user.SalesUnitID.ToString());
                    if (saleUnit != null)
                    {
                        using (Context ctx = new Context()) 
                        {
                            int state = (int)OrderState.Complete;
                            if (month)
                            {
                                var now = DateTime.Now;
                                var begin = new DateTime(now.Year,now.Month,1);
                                var end = begin.AddMonths(1).AddDays(-1).Add(new TimeSpan(23, 59, 59));
                                var list = ctx.Order.Where(c => c.SalesUnitID == saleUnit.ID && c.State == state
                                    && c.OrderTime >= begin
                                    && c.OrderTime <= end
                                    ).Select(c=>c.TotalMoney)
                                    .ToList();
                                if (list != null && list.Any())
                                {
                                    return list.Sum();
                                }
                            }
                            else
                            {
                                var list = ctx.Order.Where(c => c.SalesUnitID == saleUnit.ID && c.State == state)
                                    .Select(c=>c.TotalMoney)
                                    .ToList();
                                if (list != null && list.Any())
                                {
                                    return list.Sum();
                                }
                            }
                        }
                    }
                }
            }
            return 0;
        }
        public static ItemListBox<Orderdetail> GetSalesItem(string userName, int category, int timespan, int state, int page = 0, int pageSize = 20)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                var user = new User().Find(userName);
                if (user != null && user.SalesUnitID > 0)
                {
                    var saleUnit = new Salesunit().Find(user.SalesUnitID.ToString());
                    if (saleUnit != null)
                    {
                        using (Context ctx = new Context())
                        {
                            var expression = (from d in ctx.Orderdetail
                                        join o in ctx.Order
                                          on d.OrderID equals o.ID
                                        join g in ctx.Goods
                                          on d.GoodsID equals g.ID
                                        where o.SalesUnitID == saleUnit.ID && d.GoodsID > 0
                                        orderby o.OrderTime descending
                                        select new { d, o, g });
                            if (category > 0)
                            {
                                expression = expression.Where(c => c.g.GoodsCategoryID == category);
                            }
                            if (timespan > 0)
                            {
                                DateTime start = DateTime.Now;
                                DateTime end = DateTime.Now;
                                switch (timespan)
                                { 
                                    case 1:
                                        start = new DateTime(start.Year, 1, 1);
                                        end = new DateTime(end.Year, 4, 1).AddDays(-1).Add(new TimeSpan(23,59,59));
                                        break;
                                    case 2:
                                        start = new DateTime(start.Year, 4, 1);
                                        end = new DateTime(end.Year, 7, 1).AddDays(-1).Add(new TimeSpan(23, 59, 59));
                                        break;
                                    case 3:
                                        start = new DateTime(start.Year, 7, 1);
                                        end = new DateTime(end.Year, 10, 1).AddDays(-1).Add(new TimeSpan(23, 59, 59));
                                        break;
                                    case 4:
                                        start = new DateTime(start.Year, 10, 1);
                                        end = new DateTime(end.Year + 1, 1, 1).AddDays(-1).Add(new TimeSpan(23, 59, 59));
                                        break;
                                }
                                expression = expression.Where(c => c.o.OrderTime >= start && c.o.OrderTime <= end);
                            }
                            if (state > 0)
                            {
                                if (state == 3 || state == 4)
                                {
                                    expression = expression.Where(c => c.o.State == state);
                                }
                                else
                                {
                                    expression = expression.Where(c => c.o.State != 3 && c.o.State != 4);
                                }
                            }
                            return new ItemListBox<Orderdetail>(expression.Skip(page * pageSize)
                                      .Take(pageSize)
                                      .ToList()
                                      .Select(c => new Orderdetail().Set(c.d).LoadOrder(c.o).LoadGoods(c.g,null))
                                      .ToList()).BuildPage(
                                      expression.Count(), page, pageSize, 
                                      new PageParameter() { 
                                          IsActive = true,
                                          Script="changePage(this)",
                                          Style = "home" 
                                      });
                        }
                    }
                }
            }
            return null;
        }
        #endregion

    }
    public class OrderModel
    {
        public Goods goods{get;set;}
        public int Amount{get;set;}
    }
}
